#pragma once

#include "../comm/httplib.h"
#include "mysqlConn.hpp"

#include <jsoncpp/json/json.h>
#include <mysql/mysql.h>
#include <sw/redis++/redis++.h>

#include <iostream>
#include <regex>
#include <string>

using namespace std;

//使用正则表达式验证账号和密码的合法性
inline bool validateCredentials(const string& username, const string& password) 
{
    // 定义用户名的正则表达式
    regex usernamePattern("^[a-zA-Z0-9._-]{3,}$");
    // 定义密码的正则表达式
    regex passwordPattern("^[a-zA-Z0-9._-]{6,}$");

    // 使用regex_match进行匹配，注意这里应该是&&操作，因为两个条件都需要满足
    if(regex_match(username, usernamePattern) && regex_match(password, passwordPattern))
        return true; // 如果都匹配成功，则返回true
    else
        return false; // 否则返回false
}


// 尝试插入用户信息，成功返回 true，失败返回 false
inline bool RegisterInfo(const char *username, const char *password)
{
    const std::string host = "127.0.0.1";
    const std::string user = "oj_client";
    const std::string passwd = "lkm20031030";
    const std::string db = "oj";

    //判断用户账号和密码的合法性
    if(!validateCredentials(username, password))
        return false;

    // 进行数据库连接
    MysqlConn conn(host,user,passwd,db);

    // 构造SQL插入语句
    string query = "INSERT INTO users (username, password) VALUES ('" + string(username) + "', '" + string(password) + "')";

    //执行sql语句
    conn.executeSql(query);

    return true;
}

//将用户的用户名和密码信息在redis中缓存一份
inline void AddToRedis(const string& username, const string& password)
{   
    string redisconn = "tcp://127.0.0.1:6379";
    //创建redis对象
    sw::redis::Redis redis(redisconn);
    //使用hashtable类型来存储用户名和密码信息
    redis.hset("user:username:password", username, password);
}

inline void handle_register(const httplib::Request &request, httplib::Response &response)
{
    // 检查请求方法是否为POST
    if (request.method != "POST")
    {
        response.status = 405; // Method Not Allowed
        response.body = "Only POST requests are allowed for login.";
        return;
    }

    // 检查Content-Type是否为application/json
    string contentType = request.get_header_value("Content-Type");
    if (contentType.find("application/json") == string::npos)
    {
        response.status = 415; // Unsupported Media Type
        response.body = "Login request must have a Content-Type of application/json.";
        return;
    }

    size_t contentLength = 0;
    // 获取请求正文长度
    if(request.has_header("Content-Length"))
        contentLength = stoi(request.get_header_value("Content-Length"));
    if (contentLength == 0)
    {
        //如果正文长度为0
        response.status = 400; // Bad Request
        response.body = "Login request must have a non-empty JSON body.";
        return;
    }

    // 读取请求正文
    string requestBody(request.body, 0, contentLength);

    // 使用JsonCpp库解析请求正文
    Json::Value root;
    Json::Reader reader;
    reader.parse(requestBody,root);
    

    // 提取账号和密码
    string username = root["username"].asString();
    string password = root["password"].asString();

    // 实现账号和密码验证逻辑,验证成功则插入数据库
    bool isValid = RegisterInfo(username.c_str(), password.c_str());
    
    

    if (isValid)
    {
        // 把信息在Redis中缓存一份
        AddToRedis(username, password);

        // 账号和密码验证成功
        response.status = 200; // OK
        response.set_header("Content-Type", "application/json");
        response.body = "{\"message\":\"Login successful\"}";
    }
    else
    {
        // 账号和密码验证失败
        response.status = 401; // Unauthorized
        response.set_header("Content-Type", "application/json");
        response.body = "{\"message\":\"Invalid username or password\"}";
    }
}